package pratice.fengzhongye.interview;

import org.junit.Before;
import org.junit.Test;

import java.io.*;

/**
 * @author 吴宇亮 on 2019/2/21 0021 15:48
 */
public class Lesson28_Clone {

    Student s1;

    @Before
    public void before(){
        s1 = new Student("学生1", new Teacher("老师1"));
        System.out.println(s1);
        System.out.println("----------------------");
    }

    @Test
    public void test() throws CloneNotSupportedException {
        //Object的clone方法是浅拷贝
        Student s2 = s1.clone();
        System.out.println(s2);

        System.out.println(s1 == s2);
        System.out.println(s1.getTeacher() == s2.getTeacher());
    }

    @Test
    public void test2() throws IOException, ClassNotFoundException {
        Student s2 = s1.deepCloneBySerilizable();
        System.out.println(s1 == s2);
        System.out.println(s1.getTeacher() == s2.getTeacher());
    }

    //protected访问修饰符，一定要是同包下或者子类才能访问，同包下的子包也不能访问
    protected void Hello(){
        System.out.println("hello");
    }
}

class Student implements Cloneable, Serializable {

    private String name;
    private Teacher teacher;

    //深克隆
    public Student deepClone() throws CloneNotSupportedException {
        Student studnet = (Student) super.clone();
        studnet.teacher = studnet.teacher.clone();
        return studnet;
    }

    //利用序列化进行深克隆
    public Student deepCloneBySerilizable() throws IOException, ClassNotFoundException {
        //先把当前对象读到 字节数组输出流里面
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);

        //将 字节数组输出流 还原成 对象
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return (Student)ois.readObject();
    }

    //浅克隆
    @Override
    public Student clone() throws CloneNotSupportedException {
        return (Student)super.clone();
    }

    public Student(String name, Teacher teacher) {
        this.name = name;
        this.teacher = teacher;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    @Override
    public String toString() {
        return "student{" +
                "name='" + name + '\'' +
                ", teacher=" + teacher +
                '}';
    }
}

class Teacher implements Cloneable, Serializable {

    private String name;

    @Override
    public Teacher clone() throws CloneNotSupportedException {
        return (Teacher)super.clone();
    }

    public Teacher(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                '}';
    }
}
